Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge TraceLayout into TraceInfo #245

Merged
merged 31 commits into from
Feb 21, 2024

Conversation

plafer
Copy link
Contributor

@plafer plafer commented Feb 15, 2024

This is in preparation for #240.

The initial reason for this PR was to prepare for the introduction of the Lagrange kernel. Specifically, TraceLayout stored the number of random elements aux_segment_rands needed by the auxiliary trace; with the Lagrange kernel transition constraint, this number is a function of the trace length (specifically log(trace_length)). So the trace length should be stored in the same struct as aux_segment_rands.

Ultimately I found that the cleanest solution was to collapse the TraceLayout into the TraceInfo. As an aside, a "trace layout" without all the layout information (i.e. missing trace length) didn't make sense to me. I also found that this change cleaned things up, specifically since TraceInfo was stored "in parts" in multiple places (new to a TraceLayout) - we now properly store a single TraceInfo object in these cases.

This change also remove a bunch of methods across the board, which in my opinion simplifies the general API. For example, the only way to get a trace length now is through a TraceInfo object (unless I missed some), and all traces return their TraceInfo.

@plafer plafer mentioned this pull request Feb 16, 2024
3 tasks
Copy link
Collaborator

@irakliyk irakliyk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you! Looks good! I left some comments inline - but nothing major.

The original motivation for having TraceInfo and TraceLayout be separate was that TraceLayout was supposed to be independent from a specific instance of a computation (i.e., would not depend on trace length). But I don't think this is actually needed in practice - so, merging them is a good improvement.

Comment on lines +29 to +30
aux_segment_widths: [usize; NUM_AUX_SEGMENTS],
aux_segment_rands: [usize; NUM_AUX_SEGMENTS],
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment for the future: if we assume that there will only be a single auxiliary trace segment, we can simplify these to be primitive values rather than arrays.

air/src/air/trace_info.rs Show resolved Hide resolved
air/src/proof/mod.rs Outdated Show resolved Hide resolved
air/src/proof/context.rs Outdated Show resolved Hide resolved
math/src/utils/mod.rs Outdated Show resolved Hide resolved
prover/src/trace/mod.rs Outdated Show resolved Hide resolved
prover/src/trace/mod.rs Show resolved Hide resolved
Comment on lines 83 to 91
/// Returns the number of columns in the main segment of this trace.
fn main_trace_width(&self) -> usize {
self.layout().main_trace_width()
}

/// Returns the number of columns in all auxiliary trace segments.
fn aux_trace_width(&self) -> usize {
self.layout().aux_trace_width()
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar comment to the one above: maybe it is worth keeping these as separate methods?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reintroduced them too.

For the future though, I find selectively introducing passthrough methods for some of the TraceInfo method and not others can add confusion. For example, instead of knowing that all trace parameters are in the TraceInfo, accessible through Trace::info(), I have to remember/double-check if that one method I has a passthrough. This was the original motivation for removing all passthroughs.

This is more of a nit/personal preference though.

prover/src/trace/trace_lde/default/mod.rs Show resolved Hide resolved
prover/src/trace/trace_lde/mod.rs Show resolved Hide resolved
@plafer plafer requested a review from irakliyk February 20, 2024 13:38
@plafer
Copy link
Contributor Author

plafer commented Feb 20, 2024

@irakliyk should we fix the new redundant imports clippy errors in another PR? There are a lot of them (more than the CI shows), and it might require a change in how core_utils works (not sure).

Copy link
Collaborator

@irakliyk irakliyk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! Thank you! I left a few minor comments inline - but other than that, this is good to merge.

math/src/field/traits.rs Outdated Show resolved Hide resolved
air/src/proof/context.rs Outdated Show resolved Hide resolved
math/src/field/traits.rs Outdated Show resolved Hide resolved
Comment on lines 281 to 290
fn from_byte_vec_with_padding(mut bytes: Vec<u8>) -> Self {
assert!(bytes.len() < Self::ELEMENT_BYTES);

/// Returns a canonical integer representation of this field element.
fn as_int(&self) -> Self::PositiveInteger;
bytes.resize(Self::ELEMENT_BYTES, 0);

match Self::try_from(bytes.as_slice()) {
Ok(element) => element,
Err(_) => panic!("element deserialization failed"),
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Potential optimization: I wonder if we should change the function signature to:

fn from_bytes_with_padding(bytes: &[u8]) -> Self

This would avoid the need to call to_vec() for the users of this function which could save on heap allocations. Internally, we could use an array buffer like so:

let mut buf = [0; Self::ELEMENT_BYTES];
buf[..bytes.len()].copy_from_slice(bytes);

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This gives me this error:

error: constant expression depends on a generic parameter
   --> math/src/field/traits.rs:286:27
    |
286 |         let mut buf = [0; Self::ELEMENT_BYTES];
    |                           ^^^^^^^^^^^^^^^^^^^
    |
    = note: this may fail depending on what value the parameter takes

I did a little digging, and this seems to be a part of Rust that is still rough around the edges. IIUC, the problem is currently that there is no syntax to write the trait bounds for Self::ELEMENT_BYTES that the compiler needs to ensure soundness.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would probably still change the method signature and do .to_vec() internally. This way, when we can do it properly in the future, we can make the change only in one place.

Copy link
Contributor Author

@plafer plafer Feb 21, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed.

Note that the let element = ...; variable was necessary to avoid the compiler complaining about lifetimes.

air/src/air/trace_info.rs Show resolved Hide resolved
@irakliyk
Copy link
Collaborator

@irakliyk should we fix the new redundant imports clippy errors in another PR? There are a lot of them (more than the CI shows), and it might require a change in how core_utils works (not sure).

Yes - let's address these in a separate PR.

@plafer plafer requested a review from irakliyk February 21, 2024 14:05
@plafer
Copy link
Contributor Author

plafer commented Feb 21, 2024

@irakliyk everything should be good to go now

@irakliyk irakliyk changed the base branch from main to next February 21, 2024 21:57
Copy link
Collaborator

@irakliyk irakliyk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All looks good! Thank you!

@irakliyk irakliyk merged commit 5954c1b into facebook:next Feb 21, 2024
9 checks passed
irakliyk pushed a commit that referenced this pull request Mar 18, 2024
irakliyk pushed a commit that referenced this pull request May 9, 2024
irakliyk pushed a commit that referenced this pull request May 9, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants